package com.sma.backend.config;


import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp2.BasicDataSourceFactory;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

/**** imports ****/

@Configuration
//扫描包
@ComponentScan(basePackages = "com.sma.*",
        excludeFilters = {
                @Filter(type = FilterType.ANNOTATION,
                        classes = {Controller.class, RestController.class}
                ),
                @Filter(type = FilterType.ANNOTATION,
                        classes = {EnableWebMvc.class}
                )
        }
)
//驱动事务管理器
@EnableTransactionManagement
// MyBatis映射器接口扫描
@MapperScan(
        // 扫描包
        basePackages = "com.sma",
        // 限制注解
        annotationClass = Mapper.class)
public class BackendConfig implements TransactionManagementConfigurer {

    // 数据源
    private DataSource dataSource = null;

    /**
     * 配置数据源
     *
     * @return 数据源
     */
    @Bean(name = "dataSource")
    public DataSource initDataSource() {
        if (dataSource != null) {
            return dataSource;
        }
        Properties props = new Properties();
        props.setProperty("driverClassName", "com.mysql.jdbc.Driver");
        props.setProperty("url", "jdbc:mysql://localhost:3306/ssm");
        props.setProperty("username", "root");
        props.setProperty("password", "123456");
        props.setProperty("maxActive", "200");
        props.setProperty("maxIdle", "20");
        props.setProperty("maxWait", "30000");
        try {
            dataSource = BasicDataSourceFactory.createDataSource(props);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dataSource;
    }

    /**
     * 初始化jdbcTemplate
     *
     * @param dataSource 数据源
     * @return JdbcTemplate
     */
    @Bean(name = "jdbcTemplate")
    public JdbcTemplate initjdbcTemplate(@Autowired DataSource dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }

    /**
     * 实现接口方法，使得返回数据库事务管理器
     *
     * @return 事务管理器
     */
    @Override
    @Bean(name = "transactionManager")
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        DataSourceTransactionManager transactionManager
                = new DataSourceTransactionManager();
        // 设置事务管理器管理的数据源
        transactionManager.setDataSource(initDataSource());
        return transactionManager;
    }

    /**
     * 创建SqlSessionFactory
     *
     * @param dataSource —— 数据源
     * @return SqlSessionFactory
     * @throws Exception
     */
    @Bean("sqlSessionFactory")
    public SqlSessionFactory createSqlSessionFactoryBean(
            @Autowired DataSource dataSource) throws Exception {
        // 配置文件
        String cfgFile = "mybatis-config.xml";
        SqlSessionFactoryBean sqlSessionFactoryBean
                = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        // 配置文件
        Resource configLocation = new ClassPathResource(cfgFile);
        sqlSessionFactoryBean.setConfigLocation(configLocation);
        return sqlSessionFactoryBean.getObject();
    }

}
